// Agreement.cs
//
// Copyright (c) 2007 Mike Strobel
//
// This source code is subject to the terms of the Microsoft Reciprocal License (Ms-RL).
// For details, see <http://www.opensource.org/licenses/ms-rl.html>.
//
// All other rights reserved.

using System;
using System.Collections.Generic;

using Supremacy.Entities;
using Supremacy.Game;

using System.Linq;

namespace Supremacy.Diplomacy
{
    [Serializable]
    public class Agreement
    {
        public const int NotEnded = -1;

        private readonly Proposal _proposal;
        private readonly TurnNumber _turnAccepted;
        private TurnNumber _turnEnded = TurnNumber.Undefined;

        public Civilization Sender
        {
            get { return _proposal.Sender; }
        }

        public Civilization Recipient
        {
            get { return _proposal.Recipient; }
        }

        public Proposal Proposal
        {
            get { return _proposal; }
        }

        public int TurnAccepted
        {
            get { return _turnAccepted; }
        }

        public int TurnEnded
        {
            get { return _turnEnded; }
        }

        internal bool CheckActive()
        {
            if (!_turnEnded.IsUndefined)
                return false;
            var firstEndedStipulation = GetAllStipulations()
                .Where(o => o.IsTerminated)
                .OrderBy(o => o.TurnEnded)
                .FirstOrDefault();
            if (firstEndedStipulation == null)
                return true;
            _turnEnded = firstEndedStipulation.TurnEnded;
            return false;
        }

        protected internal IEnumerable<Stipulation> GetAllStipulations()
        {
            foreach (Stipulation stipulation in _proposal.OfferStipulations)
                yield return stipulation;
            foreach (Stipulation stipulation in _proposal.DemandStipulations)
                yield return stipulation;
        }

        public bool IsActive
        {
            get
            {
                if (_turnEnded.IsUndefined)
                {
                    return true;
                }
                else
                {
                    foreach (Stipulation stipulation in _proposal.OfferStipulations)
                    {
                        if (stipulation.IsPending || stipulation.IsInEffect)
                        {
                            return true;
                        }
                    }
                    foreach (Stipulation stipulation in _proposal.DemandStipulations)
                    {
                        if (stipulation.IsPending || stipulation.IsInEffect)
                        {
                            return true;
                        }
                    }
                    return false;
                }
            }
        }

        public Agreement(Proposal proposal)
        {
            if (proposal == null)
                throw new ArgumentNullException("proposal");
            _proposal = proposal;
            _turnAccepted = GameContext.Current.TurnNumber;
            foreach (Stipulation stipulation in _proposal.OfferStipulations)
            {
                stipulation.TurnStarted = _turnAccepted;
            }
            foreach (Stipulation stipulation in _proposal.DemandStipulations)
            {
                stipulation.TurnStarted = _turnAccepted;
            }
        }
    }
}
